package org.angelica.aliyun.manager;

import com.aliyun.openservices.log.Client;
import com.aliyun.openservices.log.common.QueriedLog;
import com.aliyun.openservices.log.exception.LogException;
import com.aliyun.openservices.log.request.GetHistogramsRequest;
import com.aliyun.openservices.log.request.GetLogsRequest;
import com.aliyun.openservices.log.response.GetHistogramsResponse;
import com.aliyun.openservices.log.response.GetLogsResponse;
import org.angelica.aliyun.entity.StsToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * 日志服务
 * @author aizhimin
 */
public class AliyunLogManager {

    private static final Logger logger = LoggerFactory.getLogger(AliyunLogManager.class);

    /**
     * 重复调用次数
     */
    private static final int RETRY_TIMES = 3;

    private static AliyunLogManager instance = new AliyunLogManager();
    private AliyunLogManager(){ }
    private static StsToken logStsToken = null;
    private static Client client = null;
    public static AliyunLogManager getInstance(StsToken stsToken){
        //token过期，则重新创建 Client
        if(logStsToken != null && !logStsToken.getSecurityToken().equals(stsToken.getSecurityToken())){
            client = null;
        }
        if(client == null){
            logStsToken = stsToken;
            client = new Client("cn-shanghai.log.aliyuncs.com",stsToken.getAccessKeyId(),stsToken.getAccessKeySecret());
            client.setSecurityToken(stsToken.getSecurityToken());
        }
        return instance;
    }

    /**
     * 查询原始日志数据
     * @param project
     * @param logstore
     * @param topic
     * @param query
     * @param from
     * @param to
     */
    public List<QueriedLog> queryOriginalLog(String project,String logstore,String topic,String query,int from,int to){
        List<QueriedLog> logList = new ArrayList<>();
        try {
            //查询日志分布情况
            GetHistogramsResponse getHistogramsResponse = null;
            while (true) {
                GetHistogramsRequest getHistogramsRequest = new GetHistogramsRequest(project, logstore, topic, query, from, to);
                getHistogramsResponse = client.GetHistograms(getHistogramsRequest);
                //  IsCompleted() 返回true，表示查询结果是准确的，如果返回false，则重复查询
                if (getHistogramsResponse != null && getHistogramsResponse.IsCompleted()) {
                    break;
                }
            }
            //日志总条数
            long totalLogLines = getHistogramsResponse.GetTotalCount();
            int logOffset = 0;
            int logLine = 100;
            while (logOffset <= totalLogLines) {
                GetLogsResponse getLogsResponse = null;
                // 对于每个 log offset,一次读取 10 行 log，如果读取失败，最多重复读取 3 次。
                for (int retryTime = 0; retryTime < RETRY_TIMES; retryTime++) {
                    GetLogsRequest getLogsRequest = new GetLogsRequest(project, logstore, from, to, topic, query, logOffset,
                            logLine, false);
                    getLogsResponse = client.GetLogs(getLogsRequest);
                    if (getLogsResponse != null && getLogsResponse.IsCompleted()) {
                        break;
                    }
                    Thread.sleep(200);
                }
                logList.addAll(getLogsResponse.GetLogs());

                logOffset += logLine;
            }

        } catch (LogException e) {
            logger.error("requestId:"+e.GetRequestId() + ",errorCode:" +e.GetErrorCode()+",errorMessage:"+e.GetErrorMessage());
        } catch (InterruptedException e) {
            logger.error(e.getMessage());
        }
        return logList;
    }

    /**
     * 查询分析日志
     * @param project
     * @param logstore
     * @param topic
     * @param query
     * @param from
     * @param to
     * @return GetLogsResponse
     */
    public GetLogsResponse queryAnalyseLog(String project, String logstore, String topic, String query, int from, int to){
        try {
            //查询日志分布情况
            GetHistogramsResponse getHistogramsResponse = null;
            while (true) {
                GetHistogramsRequest getHistogramsRequest = new GetHistogramsRequest(project, logstore, topic, query, from, to);
                getHistogramsResponse = client.GetHistograms(getHistogramsRequest);
                //  IsCompleted() 返回true，表示查询结果是准确的，如果返回false，则重复查询
                if (getHistogramsResponse != null && getHistogramsResponse.IsCompleted()) {
                    break;
                }
            }
            GetLogsRequest getLogsRequest = new GetLogsRequest(project, logstore, from, to, topic, query);
            return client.GetLogs(getLogsRequest);
        } catch (LogException e) {
            logger.error("requestId:"+e.GetRequestId() + ",errorCode:" +e.GetErrorCode()+",errorMessage:"+e.GetErrorMessage());
        }
        return null;
    }
}
